package com.example.demo.utils;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.Tesseract;
import net.sourceforge.tess4j.TesseractException;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.jsoup.Connection;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Map;
import java.util.UUID;


/**
 * @author lizijian
 */

@Slf4j
public class VerifyCodeUtil {

    private static final String HBUT_CAPTCHA_URL="http://202.114.181.8:8080/reader/captcha.php";

    private static String TESSDATA_ENV;

    static {
        TESSDATA_ENV=System.getenv("TESSDATA_PREFIX");
    }


    /**
     *    获取识别hbut验证码的orc对象
     */
    private static Tesseract getHbutTesseract(){
        Tesseract tesseract = new Tesseract();
        tesseract.setDatapath(TESSDATA_ENV);
        tesseract.setLanguage("eng");
        return tesseract;
    }
    /**
     *    获取识别hbutetc验证码的orc对象
     */
    private static Tesseract getHbutEtcTesseract(){
        Tesseract tesseract = new Tesseract();
        tesseract.setDatapath(TESSDATA_ENV);
        tesseract.setLanguage("fontyp");
        return tesseract;
    }

    /**
     * 将png图片转化为jpg格式
     */
    private static void convertPngToJpg(File file, File lastFile) {
        try {
            BufferedImage bufferedImage = ImageIO.read(file);
            BufferedImage newBufferedImage = new BufferedImage(bufferedImage.getWidth(), bufferedImage.getHeight(), BufferedImage.TYPE_INT_RGB);
            newBufferedImage.createGraphics().drawImage(bufferedImage, 0, 0, null);
            ImageIO.write(newBufferedImage, "jpg", lastFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String getHbutCardVerifyCode(Map<String,String> cookie)
        throws IOException, TesseractException {
        Response response = Jsoup.connect("http://ecard.hbut.edu.cn/SelfSearch/validateimage.ashx")
            .header("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0").cookies(cookie).ignoreContentType(true).execute();
        InputStream inputStream = response.bodyStream();
        UUID uuid = UUID.randomUUID();
        File file = new File("/usr/pic/hbut/"+uuid+".jpg");
        FileUtils.copyInputStreamToFile(inputStream, file);
        try {
            Tesseract tesseract = getHbutTesseract();
            String result = tesseract.doOCR(file);
            result = result.replace("\n", "");
            result=result.replace(" ","");
            file.delete();
            return result;
        } catch (TesseractException e) {
            log.error("orc error");
            e.printStackTrace();
            throw e;
        }
    }

    public static void main(String[] args) throws IOException, TesseractException {
        String verifyCode = getHbutCardVerifyCode(null);
        System.out.println(verifyCode);
    }

    /**
     * 读取湖北工业大学验证码
     *
     * @return 验证码
     */
    public static String getHbutVerifyCode(Map<String,String> cookie) throws IOException, TesseractException {
        Connection.Response response = Jsoup.connect(HBUT_CAPTCHA_URL).cookies(cookie).ignoreContentType(true).execute();
        InputStream inputStream = response.bodyStream();
        UUID uuid = UUID.randomUUID();
        File file = new File("/usr/pic/hbut/"+uuid+".jpg");
        FileUtils.copyInputStreamToFile(inputStream, file);
        File lastFile = new File("/usr/pic/hbut/"+uuid+"2.jpg");
        convertPngToJpg(file, lastFile);
        try {
            Tesseract tesseract = getHbutTesseract();
            String result = tesseract.doOCR(lastFile);
            result = result.replace("\n", "");
            result=result.replace(" ","");
            file.delete();
            lastFile.delete();
            return result;
        } catch (TesseractException e) {
            log.error("orc error");
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 获取湖北工业大学工程技术学院验证码
     */
    public static String getHbutEtcVerifyCode(HttpClient httpClient) throws IOException, TesseractException {
        HttpGet httpGet = new HttpGet("http://202.114.190.75/img/captcha.jpg");
        httpGet.addHeader("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64; rv:29.0) Gecko/20100101 Firefox/29.0");
        HttpResponse response = httpClient.execute(httpGet);
        while (response.getStatusLine().getStatusCode()!=200){
            System.out.println(response.getStatusLine().getStatusCode());
            response=httpClient.execute(httpGet);
        }
        HttpEntity entity = response.getEntity();
        InputStream inputStream = entity.getContent();
        UUID uuid = UUID.randomUUID();
        File file = new File("/usr/pic/hbutetc/"+uuid+".jpg");
        FileUtils.copyInputStreamToFile(inputStream,file);
        File lastFile = new File("/usr/pic/hbutetc/"+uuid+"2.jpg");
        parsePic(file,lastFile);
        try {
            Tesseract tesseract = getHbutEtcTesseract();
            String result = tesseract.doOCR(lastFile);
            result = result.replace("\n", "");
            result=result.replace(" ","");
            file.delete();
            lastFile.delete();
            return result;
        } catch (TesseractException e) {
            log.error("ocr error");
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 获取图片指定坐标的rgb值
     * @param image 图片
     */
    public static int[] getRgb(BufferedImage image, int x, int y) {
        int[] rgb = new int[3];
        int pixel = image.getRGB(x, y);
        rgb[0] = (pixel & 0xff0000) >> 16;
        rgb[1] = (pixel & 0xff00) >> 8;
        rgb[2] = (pixel & 0xff);
        return rgb;
    }

    /**
     * 将验证码转化为可识别的图片
     * @param file 原文件
     * @param storeFile 保存的文件
     */
    public static void parsePic(File file, File storeFile) throws IOException {
        BufferedImage image = ImageIO.read(file);
        int height = image.getHeight();
        int width = image.getWidth();
        int minTileX = image.getMinTileX();
        int minTileY = image.getMinTileY();
        //修复划痕
        for (int j = minTileY; j < height; j++) {
            for (int i = minTileX; i < width; i++) {
                int[] rgb = getRgb(image, i, j);
                if (rgb[0] <= 30 && rgb[1] <= 30 && rgb[2] <= 30) {
                    if (i > 0 && j > 0) {
                        int[] rgb1 = getRgb(image, i, j - 1);
                        if (rgb1[0] > 115 && rgb1[1] < 110 && rgb1[2] < 110) {
                            image.setRGB(i, j, 0xef030e);
                        }
                    }
                }
            }
        }
        //将红黑交叉部分变红
        for (int i = minTileX; i < width; i++) {
            for (int j = minTileY; j < height; j++) {
                int[] rgb = getRgb(image, i, j);
                if (rgb[0] >= 100 && rgb[1] <= 30 && rgb[2] <= 30) {
                    image.setRGB(i, j, 0xef030e);
                }
            }
        }
        //将红色部分变黑,其他部分变白
        for (int i = minTileX; i < width; i++) {
            for (int j = minTileY; j < height; j++) {
                int[] rgb = getRgb(image, i, j);
                if (rgb[0] > 115 && rgb[1] < 110 && rgb[2] < 110) {
                    image.setRGB(i, j, 0x000000);
                } else {
                    image.setRGB(i, j, 0xffffff);
                }
            }
        }
        ImageIO.write(image, "jpeg", storeFile);
    }



}
